home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-04-23 | 21.4 KB | 929 lines | [TEXT/CWIE] |
- //
- // "FinderDragPro.c"
- //
-
- #define OLDROUTINELOCATIONS 0
- #define OLDROUTINENAMES 0
- #define SystemSevenOrLater 1
-
- #include "DragManagerAdditions.h"
- #include "Technote.h"
- #include "GetIconSuiteFromFinder.h"
- #include "FileCopy.h"
- #include "DirectoryCopy.h"
-
- #ifndef __LOWMEM__
- # include <LowMem.h>
- #endif
-
- #ifndef __FONTS__
- # include <Fonts.h>
- #endif
-
- #ifndef __DIALOGS__
- # include <Dialogs.h>
- #endif
-
- #ifndef __DRAG__
- # include <Drag.h>
- #endif
-
- #ifndef __ICONS__
- # include <Icons.h>
- #endif
-
- #ifndef __PLSTRINGFUNCS__
- # include <PLStringFuncs.h>
- #endif
-
- #ifndef __TEXTUTILS__
- # include <TextUtils.h>
- #endif
-
- #ifndef __GESTALT__
- # include <Gestalt.h>
- #endif
-
- #ifndef __QDOFFSCREEN__
- # include <QDOffscreen.h>
- #endif
-
- static Boolean gQuitting; // set when it's time to quit
- static FontInfo gFontInfo; // cache for Geneva 9 info
- static Rect gIconLimitRect; // window portRect without text area
- static Boolean gHaveTranslucence; // can we call SetDragImage?
- static FSSpec gDropLocation; // cache where user dropped
- static HFSFlavor gHFSFlavor; // data dragged in, re-used when dragging out
- static DragReference gApprovedDragRef; // tracking handler approves, receive handler confirms
- static ItemReference gItemRef; // valid when gApprovedDragRef is being received
- static Handle gIconSuite; // cached from flavorTypeHFS dragged in
- static FSSpec gDropLocFSS;
- static FSSpec gCopyTarget;
- static WindowRef gWindow;
-
- static pascal OSErr InitMac (void)
- {
- //
- // Initialize the toolbox and find out
- // whether we can call SetDragImage.
- //
-
- OSErr err = noErr;
-
- MaxApplZone ( );
- if (!(err = MemError ( )))
- {
- long gestaltResponse;
-
- InitGraf (&(qd.thePort));
- InitFonts ( );
- InitWindows ( );
- InitMenus ( );
- TEInit ( );
- InitDialogs (nil);
-
- if (!(err = Gestalt (gestaltDragMgrAttr,&gestaltResponse)))
- {
- gHaveTranslucence = !!(gestaltResponse & (1 << gestaltDragMgrHasImageSupport));
- }
- }
-
- return err;
- }
-
- static pascal void MakeIconRect (Rect *iconRect)
- {
- //
- // Calculate a rectangle sized as a 32x32 icon in the center
- // of the cached icon limit rect (see gIconLimitRect above).
- //
-
- short halfLimitHeight = (gIconLimitRect.bottom - gIconLimitRect.top) / 2,
- halfLimitWidth = (gIconLimitRect.right - gIconLimitRect.left) / 2;
-
- SetRect (iconRect,0,0,32,32);
- OffsetRect (iconRect, halfLimitWidth - 16, halfLimitHeight - 16);
- }
-
- static pascal OSErr MakeDragTranslucent
- (DragReference dragRef, const Rect *iconRect, GWorldPtr *imageGWorld, RgnHandle *maskRgn)
- {
- //
- // Add a translucent image of the Finder icon to the DragReference.
- // Produces a GWorld and a Rgn to be disposed by caller after TrackDrag.
- //
-
- OSErr err = noErr;
-
- *imageGWorld = nil;
- *maskRgn = nil;
-
- if (gHaveTranslucence)
- {
- const short pixelDepth = 8;
- Rect imageRect = *iconRect;
- Point offsetPt;
-
- SetPt (&offsetPt, imageRect.left, imageRect.top);
- OffsetRect (&imageRect, -(imageRect.left), -(imageRect.top));
- LocalToGlobal (&offsetPt);
-
- err = NewGWorld (imageGWorld, pixelDepth, &imageRect, nil, nil, 0);
- if (err == memFullErr)
- err = NewGWorld (imageGWorld, pixelDepth, &imageRect, nil, nil, useTempMem);
- if (!err)
- {
- *maskRgn = NewRgn ( );
- if (!(err = MemError ( )))
- {
- if (!(err = IconSuiteToRgn (*maskRgn,&imageRect,kAlignNone,gIconSuite)))
- {
- GDHandle saveDevice;
- CGrafPtr savePort;
- PixMapHandle imagePixMap = GetGWorldPixMap (*imageGWorld);
-
- GetGWorld (&savePort, &saveDevice);
- (void) LockPixels (imagePixMap);
- SetGWorld (*imageGWorld, nil);
- EraseRect (&(qd.thePort->portRect));
- err = PlotIconSuite (&imageRect,kAlignNone,kTransformNone,gIconSuite);
- UnlockPixels (imagePixMap);
- SetGWorld (savePort, saveDevice);
-
- if (!err)
- err = SetDragImage (dragRef, imagePixMap, *maskRgn, offsetPt, dragStandardImage);
- }
- }
- }
-
- if (err)
- {
- if (*imageGWorld)
- {
- DisposeGWorld (*imageGWorld);
- *imageGWorld = nil;
- }
-
- if (*maskRgn)
- {
- DisposeRgn (*maskRgn);
- *maskRgn = nil;
- }
- }
- }
-
- return err;
- }
-
- static pascal OSErr RedundantMakeHFSFlavor (HFSFlavor *hfsFlavorP)
- {
- //
- // We could assume that any HFSFlavor we're handed thru
- // our drag receive handler is valid. However:
- //
- // [1] It might have become stale since we received it.
- //
- // [2] We need an excuse to call MakeHFSFlavor so we
- // can test it before pasting it into the Technote.
- //
- // Thus, this function confirms/refreshes the HFSFlavor data;
- // generally we're passed a pointer to the global HFSFlavor cache,
- // but this code doesn't know it.
- //
-
- OSErr err = noErr;
-
- //
- // Clear some fields so we can see that MakeHFSFlavor
- // did its job.
- //
-
- hfsFlavorP->fileType =
- hfsFlavorP->fileCreator =
- hfsFlavorP->fdFlags = 0;
-
- err = MakeHFSFlavor ( hfsFlavorP->fileSpec.vRefNum,
- hfsFlavorP->fileSpec.parID,
- hfsFlavorP->fileSpec.name,
- hfsFlavorP );
-
- return err;
- }
-
- static pascal OSErr WakeUpCurrentProcess (void)
- {
- ProcessSerialNumber curPSN = { 0, kCurrentProcess };
- return WakeUpProcess (&curPSN); // "post" a null event
- }
-
- static pascal OSErr CopyDroppedFileOrFolder
- (DragReference dragRef, ItemReference itemRef, const PromiseHFSFlavor *phfs)
- {
- //
- // Figure out where the user dropped the file or folder and create a dummy.
- // Then prepare to send an AppleEvent to Finder to overwrite the dummy.
- // Don't send the AppleEvent yet because we need to delete the dummy file
- // after TrackDrag completes so that Drag Manager doesn't display rejection
- // feedback to the user. Look at the code surrounding
- // AddTranslucentIconAndDrag's call to TrackDrag for more info.
- //
-
- OSErr err = noErr;
-
- if (!(err = GetDropDirectory (dragRef,&gDropLocFSS)))
- {
- long dropDirID;
-
- if (!(err = GetDirID (&gDropLocFSS,&dropDirID)))
- if (!(err = FSMakeFSSpec (gDropLocFSS.vRefNum, dropDirID, gHFSFlavor.fileSpec.name, &gCopyTarget)))
- err = dupFNErr;
- else if (err == fnfErr)
- if (!(err = CreatePromisedFileOrFolder (phfs,&gCopyTarget,smSystemScript)))
- err = SetPromisedHFSFlavorData (dragRef,itemRef,phfs,&gCopyTarget);
-
- if (err)
- {
- gDropLocFSS.vRefNum = 0;
- gCopyTarget.vRefNum = 0;
- }
- }
-
- return err;
- }
-
- static pascal OSErr MyDragSendDataProc
- (FlavorType flavorType, void *, ItemReference itemRef, DragReference dragRef)
- {
- //
- // This function fulfills the promise of the promisedFlavor data.
- // See comments in CopyDroppedFileOrFolder.
- //
-
- OSErr err = noErr;
-
- PromiseHFSFlavor phfs;
- Size size = sizeof (phfs);
-
- if (!(err = GetFlavorData (dragRef,itemRef,flavorTypePromiseHFS,&phfs,&size,0)))
- {
- if (size != sizeof (phfs))
- err = cantGetFlavorErr;
- else if (flavorType == phfs.promisedFlavor)
- {
- Boolean shouldCopy;
-
- if (!(err = ShouldCopyToDropLoc (dragRef,flavorType,&shouldCopy)))
- {
- if (shouldCopy)
- {
- SetCursor (*GetCursor (watchCursor));
- err = CopyDroppedFileOrFolder (dragRef,itemRef,&phfs);
- }
- else
- {
- err = SetPromisedHFSFlavorData
- (dragRef,itemRef,&phfs,&(gHFSFlavor.fileSpec));
- }
- }
- }
- }
-
- return err;
- }
-
- static pascal OSErr AttachSendDataProc (DragReference dragRef)
- {
- //
- // Cretaes a UPP for the SendDataProc if necessary
- // and attaches it to the given DragReference.
- //
-
- OSErr err = noErr;
-
- static DragSendDataProc dragSendDataProc;
-
- if (!dragSendDataProc)
- dragSendDataProc = NewDragSendDataProc (MyDragSendDataProc);
- if (!dragSendDataProc)
- err = nilHandleErr;
- else
- err = SetDragSendProc (dragRef,dragSendDataProc,nil);
-
- return err;
- }
-
- static pascal OSErr AddTranslucentIconAndDrag
- (DragReference dragRef, const EventRecord *event, const Rect *iconRect)
- {
- //
- // Add an appropriate icon to the DragReference. Drag.
- // Copy any necessary files as result from the drag.
- //
-
- OSErr err = noErr;
-
- RgnHandle dragRgn = NewRgn ( );
- if (!(err = MemError ( )))
- {
- if (!(err = IconSuiteToRgn (dragRgn,iconRect,kAlignNone,gIconSuite)))
- {
- RgnHandle insetRgn = NewRgn ( );
- if (!(err = MemError ( )))
- {
- Point globalOrigin;
- GWorldPtr imageGWorld;
- RgnHandle maskRgn;
-
- CopyRgn (dragRgn,insetRgn);
- InsetRgn (insetRgn,1,1);
- DiffRgn (dragRgn,insetRgn,dragRgn);
- SetPt (&globalOrigin,qd.thePort->portRect.left,qd.thePort->portRect.top);
- LocalToGlobal (&globalOrigin);
- OffsetRgn (dragRgn,globalOrigin.h,globalOrigin.v);
-
- (void) MakeDragTranslucent (dragRef,iconRect,&imageGWorld,&maskRgn);
- // ignore errors; we don't care very much; dispose whatever we get after
-
- err = TrackDrag (dragRef,event,dragRgn);
-
- DisposeRgn (insetRgn);
- if (!err) err = MemError ( );
-
- if (imageGWorld)
- DisposeGWorld (imageGWorld);
- if (maskRgn)
- DisposeRgn (maskRgn);
- }
- }
- DisposeRgn (dragRgn);
- if (!err) err = MemError ( );
- }
-
- return err;
- }
-
- static pascal OSErr DragOut (const EventRecord *event, const Rect *iconRect)
- {
- //
- // Administrates the process of dragging the icon out of the window.
- // If the option key is being held down, use flavorTypePromiseHFS
- // so drag receivers can ask for a copy. Make the drag translucent.
- // Copy the file via MoreFiles if appropriate.
- //
-
- OSErr err = noErr;
-
- if (WaitMouseMoved (event->where))
- {
- DragReference dragRef;
-
- if (!(err = NewDrag (&dragRef)))
- {
- OSErr err2 = noErr;
-
- if (!(event->modifiers & optionKey))
- {
- if (!(err = RedundantMakeHFSFlavor (&gHFSFlavor)))
- err = AddDragItemFlavor
- (dragRef, 0, flavorTypeHFS, &gHFSFlavor, sizeof (gHFSFlavor), 0);
- }
- else if (!(err = AttachSendDataProc (dragRef)))
- {
- FlavorType promisedFlavor =
- (event->modifiers & cmdKey) ? kPromisedFlavorFindFile : kPromisedFlavor;
- err = AddDragItemFlavorTypePromiseHFS
- (dragRef,0,gHFSFlavor.fileType,gHFSFlavor.fileCreator,
- gHFSFlavor.fdFlags,promisedFlavor);
- }
-
- if (!err)
- {
- gCopyTarget.vRefNum = 0;
- gDropLocFSS.vRefNum = 0;
-
- if (!(err = AddTranslucentIconAndDrag (dragRef,event,iconRect)))
- {
- if (!err && gDropLocFSS.vRefNum && gCopyTarget.vRefNum)
- {
- if (!(err = FSpDelete (&gCopyTarget)))
- {
- if (gHFSFlavor.fileType == 'fold' || gHFSFlavor.fileType == 'disk')
- err = FSpDirectoryCopy (&(gHFSFlavor.fileSpec),&gDropLocFSS,nil,0,true,nil);
- else
- err = FSpFileCopy (&(gHFSFlavor.fileSpec),&gDropLocFSS,nil,nil,0,true);
- }
- }
- }
- }
-
- err2 = DisposeDrag (dragRef);
- if (!err) err = err2;
- }
- }
-
- return err;
- }
-
- static pascal OSErr ClickInContent (WindowRef whichWindow, const EventRecord *event)
- {
- //
- // See if the click was in the icon. If so, highlight the icon and
- // let someone else decide whether to drag.
- //
-
- OSErr err = noErr;
-
- if (gIconSuite)
- {
- Rect iconRect;
- Point localPoint = event->where;
- GrafPtr savedPort = qd.thePort;
-
- SetPort (whichWindow);
-
- GlobalToLocal (&localPoint);
- MakeIconRect (&iconRect);
-
- if (PtInIconSuite (localPoint,&iconRect,kAlignNone,gIconSuite))
- if (!(err = PlotIconSuite (&iconRect,kAlignNone,kTransformSelected,gIconSuite)))
- {
- OSErr err2 = noErr;
- err = DragOut (event,&iconRect);
- err2 = PlotIconSuite (&iconRect,kAlignNone,kTransformNone,gIconSuite);
- if (!err) err = err2;
- }
-
- SetPort (savedPort);
- }
-
- return err;
- }
-
- static pascal OSErr MouseDown (const EventRecord *event)
- {
- OSErr err = noErr;
-
- WindowRef whichWindow;
- short partCode = FindWindow (event->where,&whichWindow);
-
- Rect boundsRect;
-
- switch (partCode)
- {
- case inContent :
-
- if (whichWindow != FrontWindow ( ))
- SelectWindow (whichWindow);
- else
- err = ClickInContent (whichWindow,event);
- break;
-
- case inGoAway :
-
- if (TrackGoAway (whichWindow,event->where))
- gQuitting = true;
- break;
-
- case inDrag :
-
- boundsRect = qd.screenBits.bounds;
- InsetRect (&boundsRect,4,4);
- DragWindow (whichWindow,event->where,&boundsRect);
- break;
- }
-
- return err;
- }
-
- static pascal void DrawCenteredString (ConstStr255Param str, short baseLine)
- {
- Rect *portRect = &(qd.thePort->portRect);
- short portWidth = portRect->right - portRect->left,
- stringWidth = StringWidth (str);
-
- MoveTo (portRect->left + (portWidth / 2) - (stringWidth / 2), baseLine);
- DrawString (str);
- }
-
- static pascal void AppendOSTypeToString (OSType ost, StringPtr str)
- {
- BlockMoveData (&ost,str+*str+1,sizeof(ost));
- *str += sizeof(ost);
- }
-
- static pascal void AppendHex16ToString (UInt16 ui, StringPtr str)
- {
- unsigned char *scan = str + *str + 1;
- unsigned char nybbleIndex = 0;
- static const char hexDigits [ ] = "0123456789ABCDEF";
-
- do
- scan [3 - nybbleIndex] = hexDigits [(ui >> (4 * nybbleIndex)) & 0x0F];
- while (++nybbleIndex < 4);
-
- *str += 4;
- }
-
- static pascal OSErr UpdateWindow (WindowRef whichWindow)
- {
- OSErr err = noErr;
-
- GrafPtr savedPort = qd.thePort;
-
- SetPort (whichWindow);
- BeginUpdate (whichWindow);
-
- EraseRect (&(qd.thePort->portRect));
-
- if (gIconSuite)
- {
- Rect iconRect;
-
- MakeIconRect (&iconRect);
-
- err = PlotIconSuite (&iconRect,kAlignNone,kTransformNone,gIconSuite);
-
- if (err == noMaskFoundErr)
- err = noErr;
-
- if (!err)
- {
- StringPtr str = nil;
- short baseLine = gIconLimitRect.bottom + gFontInfo.ascent;
-
- DrawCenteredString (gHFSFlavor.fileSpec.name, baseLine);
-
- str = (StringPtr) NewPtr (sizeof (Str255));
- if (!(err = MemError ( )))
- {
- Str15 scratch;
-
- PLstrcpy (str,"\pvRefNum ");
- NumToString (gHFSFlavor.fileSpec.vRefNum, scratch);
- PLstrcat (str,scratch);
- PLstrcat (str,"\p, parID ");
- NumToString (gHFSFlavor.fileSpec.parID, scratch);
- PLstrcat (str,scratch);
- baseLine += gFontInfo.ascent + gFontInfo.leading;
- DrawCenteredString (str, baseLine);
-
- *str = 0;
- AppendOSTypeToString (gHFSFlavor.fileType, str);
- PLstrcat (str,"\p ");
- AppendOSTypeToString (gHFSFlavor.fileCreator, str);
- PLstrcat (str,"\p 0x");
- AppendHex16ToString (gHFSFlavor.fdFlags, str);
- baseLine += gFontInfo.ascent + gFontInfo.leading;
- DrawCenteredString (str, baseLine);
-
- DisposePtr ((Ptr) str);
- if (!err) err = MemError ( );
- }
- }
- }
-
- EndUpdate (whichWindow);
- SetPort (savedPort);
-
- return err;
- }
-
- static pascal void InvalWindow (WindowRef wRef)
- {
- // "post" an update event for the entire window
-
- GrafPtr savedPort = qd.thePort;
- SetPort (wRef);
- InvalRect (&(qd.thePort->portRect));
- SetPort (savedPort);
- }
-
- static pascal OSErr RebuildIcon (WindowRef wRef)
- {
- OSErr err = noErr;
-
- if (!gIconSuite && gHFSFlavor.fileSpec.vRefNum)
- if (!(err = GetIconSuiteFromFinder (&(gHFSFlavor.fileSpec),&gIconSuite)))
- InvalWindow (wRef);
-
- return err;
- }
-
- static pascal OSErr NullEvent (void)
- {
- OSErr err = noErr;
-
- if (gWindow)
- if (!(err = RebuildIcon (gWindow)))
- ;
-
- return err;
- }
-
- static pascal OSErr OneEvent (const EventRecord *event)
- {
- OSErr err = noErr;
-
- switch (event->what)
- {
- case kHighLevelEvent :
-
- err = AEProcessAppleEvent (event);
- break;
-
- case mouseDown :
-
- err = MouseDown (event);
- break;
-
- case updateEvt :
-
- err = UpdateWindow ((WindowRef) (event->message));
- break;
-
- case nullEvent :
-
- err = NullEvent ( );
- break;
- }
-
- return err;
- }
-
- static pascal void LoopEvents (void)
- {
- do
- {
- OSErr err;
-
- EventRecord event;
- WaitNextEvent (everyEvent,&event,-1,nil);
- err = OneEvent (&event);
- if (err) break;
- InitCursor ( );
- }
- while (!gQuitting);
- }
-
- static pascal OSErr ShowDragHiliteWindow (DragReference dragRef, WindowRef wRef)
- {
- OSErr err = noErr;
-
- RgnHandle hiliteRgn = NewRgn ( );
- if (!hiliteRgn)
- err = nilHandleErr;
- else
- {
- RectRgn (hiliteRgn,&(wRef->portRect));
- err = ShowDragHilite (dragRef,hiliteRgn,true);
- DisposeRgn (hiliteRgn);
- }
-
- return err;
- }
-
- static pascal OSErr ApproveDragReference (DragReference theDragRef, Boolean *approved)
- {
- //
- // We accept one item and one item only.
- // It must have either 'flavorTypeHFS' or 'flavorTypePromiseHFS'.
- // If the user held the option key down when beginning the drag
- // or is holding the option key down when the drag enters, we
- // accept only 'flavorTypePromiseHFS'.
- //
- // Note that if a flavor can't be found, it's not really an
- // error; it only means the flavor wasn't there and we should
- // not accept the drag. Therefore, we translate 'badDragFlavorErr'
- // into a 'false' value for '*approved'.
- //
-
- OSErr err = noErr;
-
- UInt16 itemCount;
- DragAttributes dragAttrs;
- short currentModifers,
- mouseDownModifiers;
-
- *approved = false;
-
- if (!(err = GetDragAttributes (theDragRef,&dragAttrs)))
- if (!(dragAttrs & dragInsideSenderWindow))
- if (!(err = CountDragItems (theDragRef,&itemCount)) && itemCount == 1)
- if (!(err = GetDragItemReferenceNumber (theDragRef,1,&gItemRef)))
- if (!(err = GetDragModifiers (theDragRef,¤tModifers,&mouseDownModifiers,nil)))
- {
- if ((currentModifers & optionKey) || (mouseDownModifiers & optionKey))
- err = badDragFlavorErr; // pretend to have searched and not found
- else
- {
- FlavorFlags flavorFlags;
- err = GetFlavorFlags (theDragRef,gItemRef,flavorTypeHFS,&flavorFlags);
- }
-
- if (!err)
- *approved = true;
- else if (err == badDragFlavorErr)
- {
- PromiseHFSFlavor promiseHFSFlavor;
- Size dataSize;
-
- dataSize = sizeof (promiseHFSFlavor);
- err = GetFlavorData (theDragRef,gItemRef,flavorTypePromiseHFS,&promiseHFSFlavor,&dataSize,0);
-
- if (err == badDragFlavorErr)
- err = noErr; // *approved = false;
- else if (!err)
- {
- if (dataSize != sizeof (promiseHFSFlavor))
- err = cantGetFlavorErr;
- else
- *approved = true;
- }
- }
- }
-
- return err;
- }
-
- static pascal OSErr MyDragTrackingHandler
- (DragTrackingMessage message, WindowPtr theWindow, void *, DragReference theDragRef)
- {
- Boolean approved;
-
- switch (message)
- {
- case dragTrackingEnterWindow :
-
- if (!ApproveDragReference (theDragRef,&approved) && approved)
- if (!ShowDragHiliteWindow (theDragRef,theWindow))
- gApprovedDragRef = theDragRef;
- break;
-
- case dragTrackingInWindow :
-
- // do nothing
- break;
-
- case dragTrackingLeaveWindow :
-
- (void) HideDragHilite (theDragRef);
- // fall thru
-
- default :
-
- gApprovedDragRef = nil;
- break;
- }
-
- return noErr; // there's no point in confusing Drag Manager or its caller
- }
-
- static pascal OSErr MyDragReceiveHandler (WindowPtr, void *, DragReference theDragRef)
- {
- //
- // Receive a drag.
- //
- // First attempt to grab flavorTypePromiseHFS data
- // without specifying a drop location to induce Find File to
- // reveal its secrets. If we're not dealing
- // with Find File, make sure there's a folder to receive
- // the new file and and receive the file there.
- //
- // Once the file's been received, we need a null event sent
- // to our event loop because that's when we check to see if
- // gHFSFlavor has changed. Since Drag Manager callbacks run
- // outside the event loop, we might otherwise only receive
- // a null event after quite a long time, especially if we
- // specify a long sleep time when calling WaitNextEvent.
- // (See RebuildIcon and its caller.)
- //
-
- OSErr err = dragNotAcceptedErr;
-
- if (theDragRef == gApprovedDragRef)
- {
- err = GetHFSFlavorFromDragReference (gApprovedDragRef,gItemRef,&gHFSFlavor);
-
- if (err == badDragFlavorErr)
- {
- err = ReceivePromisedFile (gApprovedDragRef,gItemRef,&gHFSFlavor,nil);
-
- if (err == paramErr) // it's not from Find File
- {
- if (*(gDropLocation.name))
- err = noErr;
- else
- {
- // real programs don't use string constants
- err = FSMakeFSSpec (0,0,"\pDropSpool",&gDropLocation);
- if (err == fnfErr)
- {
- long createdDirID;
- // specify smRoman because of the string constant
- err = FSpDirCreate (&gDropLocation,smRoman,&createdDirID);
- }
- }
-
- if (!err)
- err = ReceivePromisedFile
- (gApprovedDragRef,gItemRef,&gHFSFlavor,&gDropLocation);
- }
- }
-
- if (!err)
- {
- if (!(err = WakeUpCurrentProcess ( )))
- {
- if (gIconSuite)
- {
- DisposeIconSuite (gIconSuite,true);
- gIconSuite = nil;
- }
- }
- }
- }
-
- return err;
- }
-
- static pascal OSErr CreateFinderDragProWindow (void)
- {
- OSErr err = noErr;
-
- DragReceiveHandlerUPP dragReceiveHandlerUPP = nil;
- DragTrackingHandlerUPP dragTrackingHandlerUPP = nil;
- Rect boundsRect;
- unsigned short top;
-
- gWindow = nil;
-
- top = qd.screenBits.bounds.top + GetMBarHeight ( ) + 20;
- SetRect (&boundsRect, 20, top + 50, 200, top + 150);
-
- gWindow = NewCWindow
- (nil, &boundsRect, LMGetCurApName ( ), true, noGrowDocProc, (WindowRef) -1, true, 0);
-
- if (!gWindow)
- err = nilHandleErr;
- else
- {
- dragTrackingHandlerUPP = NewDragTrackingHandlerProc (MyDragTrackingHandler);
-
- if (!dragTrackingHandlerUPP)
- err = nilHandleErr;
- else
- {
- dragReceiveHandlerUPP = NewDragReceiveHandlerProc (MyDragReceiveHandler);
-
- if (!dragReceiveHandlerUPP)
- err = nilHandleErr;
- else if (!(err = InstallTrackingHandler (dragTrackingHandlerUPP,gWindow,nil)))
- {
- err = InstallReceiveHandler (dragReceiveHandlerUPP,gWindow,nil);
- if (err)
- RemoveTrackingHandler (dragTrackingHandlerUPP,gWindow);
- else
- {
- GrafPtr savedPort = qd.thePort;
- SetPort (gWindow);
- TextSize (9);
- GetFontInfo (&gFontInfo);
- gIconLimitRect = qd.thePort->portRect;
- gIconLimitRect.bottom -= 3 * (gFontInfo.ascent + gFontInfo.leading + gFontInfo.descent);
- SetPort (savedPort);
- }
- }
- }
- }
-
- if (err)
- {
- if (gWindow) DisposeWindow (gWindow);
- if (dragTrackingHandlerUPP) DisposeRoutineDescriptor (dragTrackingHandlerUPP);
- if (dragReceiveHandlerUPP) DisposeRoutineDescriptor (dragReceiveHandlerUPP);
-
- gWindow = nil;
- }
-
- return err;
- }
-
- static pascal OSErr NewApplicationAppleEventHandler (const AppleEvent *, AppleEvent *, long)
- {
- (void) CreateFinderDragProWindow ( );
- return noErr;
- }
-
- void main (void)
- {
- if (InitMac ( ))
- SysBeep (10);
- else
- {
- (void) InstallBogusFinderEventHandler ( );
- AEInstallEventHandler (kCoreEventClass,kAEOpenApplication,
- NewAEEventHandlerProc (NewApplicationAppleEventHandler),0,false);
- LoopEvents ( );
- }
- }
-